package com.github.liuche51.easyTaskL.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.liuche51.easyTask.core.AnnularQueue;
import com.github.liuche51.easyTask.core.TaskType;
import com.github.liuche51.easyTask.core.TimeUnit;
import com.github.liuche51.easyTask.dto.zk.ZKNode;
import com.github.liuche51.easyTask.monitor.AnnularQueueMonitor;
import com.github.liuche51.easyTask.monitor.ClusterMonitor;
import com.github.liuche51.easyTask.util.DateUtils;
import com.github.liuche51.easyTaskL.service.TestService;
import com.github.liuche51.easyTaskL.task.CusTask1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.time.ZonedDateTime;
import java.util.*;

@Controller
@RequestMapping("/m")
public class MultipleController {
    private static Logger log = LoggerFactory.getLogger(MultipleController.class);
    private List<String> onceList=new LinkedList<>();
    private List<String> perioList=new LinkedList<>();
    @Value("${easyTaskL.serverPort}")
    private int serverPort;
    @Autowired
    private TestService testService;

    @RequestMapping("/index")
    public ModelAndView index() {
        ModelAndView view = new ModelAndView("multiple.jsp");
        view.addObject("node", serverPort);
        return view;
    }

    @RequestMapping("/once")
    @ResponseBody
    public String once(@RequestParam("name") String name, @RequestParam("time") int time, @RequestParam("count") int count,
                       @RequestParam("threadqty") int threadqty) {
        List<Thread> list = new ArrayList<>(threadqty);
        Map<String, String> param = new HashMap<String, String>() {
            {
                put("name", name);
                put("birthday", "1996-1-1");
                put("age", "28");
                put("threadid", String.valueOf(Thread.currentThread().getId()));
            }
        };
        for (int i = 0; i < threadqty; i++) {
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int y=0;y<count;y++){
                        CusTask1 task1 = new CusTask1();
                        task1.setEndTimestamp(ZonedDateTime.now().plusSeconds(time).toInstant().toEpochMilli());
                        task1.setParam(param);
                        try {
                            onceList.add(AnnularQueue.getInstance().submitAllowWait(task1)+"("+ DateUtils.getCurrentDateTime() +")");
                        } catch (Exception e) {
                            log.error("", e);
                        }
                    }
                }
            });
            list.add(th);
        }
        list.forEach(x -> {
            x.start();
        });
        return "true";
    }

    @RequestMapping("/period")
    @ResponseBody
    public String period(@RequestParam("name") String name, @RequestParam("period") int period, @RequestParam("immediately") int immediately,
                         @RequestParam("count") int count, @RequestParam("threadqty") int threadqty) {
        List<Thread> list = new ArrayList<>(threadqty);
        Map<String, String> param2 = new HashMap<String, String>() {
            {
                put("name", name);
                put("birthday", "1996-1-1");
                put("age", "28");
                put("threadid", String.valueOf(Thread.currentThread().getId()));
            }
        };

        for (int i = 0; i < threadqty; i++) {
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int y=0;y<count;y++){
                        CusTask1 task2 = new CusTask1();
                        task2.setEndTimestamp(ZonedDateTime.now().plusSeconds(immediately == 1 ? -1 : 1).toInstant().toEpochMilli());
                        task2.setTaskType(TaskType.PERIOD);
                        task2.setUnit(TimeUnit.SECONDS);
                        task2.setParam(param2);
                        try {
                            task2.setPeriod(period);
                            perioList.add(AnnularQueue.getInstance().submitAllowWait(task2)+"("+ DateUtils.getCurrentDateTime() +")");
                        } catch (Exception e) {
                            log.error("", e);
                        }
                    }
                }
            });
            list.add(th);
        }
        list.forEach(x -> {
            x.start();
        });
        return "true";
    }
    @RequestMapping("/getOnceTaskID")
    @ResponseBody
    public String getOnceTaskID() {
        StringBuilder builder = new StringBuilder();
       Iterator<String> items= onceList.iterator();
       while (items.hasNext()){
            builder.append(items.next()).append("<br>");
       }
        return builder.toString();
    }
    @RequestMapping("/getPeriodTaskID")
    @ResponseBody
    public String getPeriodTaskID() {
        StringBuilder builder = new StringBuilder();
        Iterator<String> items= perioList.iterator();
        while (items.hasNext()){
            builder.append(items.next()).append("<br>");
        }
        return builder.toString();
    }
    @RequestMapping("/clearTaskInfo")
    @ResponseBody
    public String clearTaskInfo() {
        CusTask1.queue.clear();
        onceList.clear();
        perioList.clear();
        return "true";
    }
    @RequestMapping("/taskInfo")
    @ResponseBody
    public List<String> taskInfo() {
        List<String> list = new LinkedList<>();
        while (CusTask1.queue.size() > 0) {
            list.add(CusTask1.queue.poll());
        }
        return list;
    }
    @RequestMapping("/getZKNode")
    @ResponseBody
    public String getZKNode() {
        ZKNode node= null;
        try {
            node = ClusterMonitor.getCurrentZKNodeInfo();
        } catch (Exception e) {
           log.error("",e);
        }
        return JSONObject.toJSONString(node);
    }
    @RequestMapping("/getPoolsInfo")
    @ResponseBody
    public Map<String, Object> getPoolsInfo() {
        Map<String, Object> map = new HashMap<>(3);
        try {
            map.put("waiteExcuteQty", AnnularQueueMonitor.getTaskInAnnularQueueQty());
            map.put("dispatch", AnnularQueueMonitor.getDispatchsPoolInfo());
            map.put("worker", AnnularQueueMonitor.getWorkersPoolInfo());
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    @RequestMapping("/searchDbInfo")
    @ResponseBody
    public Map<String, Map<String, List>> searchDbInfo(@RequestParam("taskId") String taskId) {
        try {
            Map<String, Map<String, List>> map = ClusterMonitor.getDBTraceInfoByTaskId(taskId);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    @RequestMapping("/deleteTask")
    @ResponseBody
    public String deleteTask(@RequestParam("id") String id){
        try {
            AnnularQueue.getInstance().delete(id);
            return "删除成功!";
        } catch (Exception e) {
            log.error("",e);
            return "删除失败!"+e.getMessage();
        }
    }
    @RequestMapping("/getNettypoolInfo")
    @ResponseBody
    public String getNettypoolInfo(){
        Map<String, String> map=ClusterMonitor.getNettyClientPoolInfo();
        return JSONObject.toJSONString(map);
    }
    @RequestMapping("/getSqlitePoolInfo")
    @ResponseBody
    public String getSqlitePoolInfo(){
        return ClusterMonitor.getSqlitePoolInfo();
    }
    @RequestMapping("/getNodeClockDifferInfo")
    @ResponseBody
    public String getNodeClockDifferInfo(){
        return JSONObject.toJSONString(ClusterMonitor.getNodeClockDifferInfo());
    }
}
